package com.users.rn.rncommon.manager;

import android.app.Application;
import android.text.TextUtils;

import androidx.annotation.Nullable;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.shell.MainReactPackage;
import com.users.rn.rncommon.basic.RNReactModulesPackage;
import com.users.rn.rncommon.model.PluginInfo;
import com.users.rn.rncommon.plugin.ReactLoadUtils;
import com.users.rn.rncommon.util.ReactUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Description:
 * @Author: bluce
 * @Date: 2020/12/3 10:45
 */
public class ALHReactNativeHost extends ReactNativeHost {
    private ArrayList<String> mLoadedComponents = new ArrayList<>();
    private ArrayList<String> mModuleIds = new ArrayList<>();
    private OnReactNativeHostListener mLoaderListener;

    public ALHReactNativeHost(Application application) {
        super(application);
        ReactInstanceManager.ReactInstanceEventListener listener = reactContext -> onReactContextInitialized(reactContext);
        getReactInstanceManager().addReactInstanceEventListener(listener);
//        if (!getReactInstanceManager().hasStartedCreatingInitialContext()) {
//            getReactInstanceManager().createReactContextInBackground();
//        }
    }

    private void onReactContextInitialized(ReactContext reactContext) {
        if (mLoaderListener != null) {
            mLoaderListener.onReactContextInitCompleted(reactContext);
        }
    }

    public boolean isHasLoadedModuleId(String moduleId) {
        int i = mModuleIds.indexOf(moduleId);
        return i != -1;
    }

    public void putModuleId(String moduleId) {
        if (!isHasLoadedModuleId(moduleId)) {
            mModuleIds.add(moduleId);
        }
    }

    /**
     * 是否debug模式，默认都是false
     *
     * @return
     */
    @Override
    public boolean getUseDeveloperSupport() {
        return false;
    }

    @Override
    protected List<ReactPackage> getPackages() {
        return Arrays.asList(
                new MainReactPackage(),
                new RNReactModulesPackage()
//                new SvgPackage()
        );
    }

    @Nullable
    @Override
    protected String getBundleAssetName() {
        return "common-rn/index.jsbundle";
    }

    /**
     * 添加页面
     *
     * @param componentName
     */
    public void addComponent(String componentName) {
        if (!TextUtils.isEmpty(componentName)) {
            mLoadedComponents.add(componentName);
        }
    }

    public void removeComponent(String pluginId, String componentName) {
        if (TextUtils.isEmpty(pluginId) || TextUtils.isEmpty(componentName)) {
            return;
        }
        mLoadedComponents.remove(componentName);
        if (mLoadedComponents.isEmpty()) {//删除对应的jsBridge
            mModuleIds.clear();
            if (getUseDeveloperSupport()) {
                ALHReactDebugHostManager.getInstance().remove(pluginId);
            } else {
                ALHReactEnvManager.getInstance().removeReactNativeHost(pluginId);
            }
        }
    }

    public void readyForReactNativeHostListener(PluginInfo pluginInfo, ReactLoadUtils.OnLoadScriptListener listener) {
        mLoaderListener = new OnReactNativeHostListener() {
            @Override
            public void handleException(Exception e) {
                ReactUtils.eventErrorBundle(getApplication(), pluginInfo, e.toString());
            }

            @Override
            public void onReactContextInitCompleted(ReactContext reactContext) {
                ReactUtils.eventBizBundle(getApplication(), pluginInfo, "ReactContext init completed now");
                ReactLoadUtils.loadBundle(ALHReactNativeHost.this, listener, pluginInfo);
            }

            @Override
            public ReactLoadUtils.OnLoadScriptListener getOnLoadScriptListener() {
                return listener;
            }

        };
    }

    public void removeListener(ReactLoadUtils.OnLoadScriptListener listener) {
        if (mLoaderListener != null && mLoaderListener.getOnLoadScriptListener() == listener) {
            mLoaderListener = null;
        }
    }

    @Override
    protected String getJSMainModuleName() {
        return "index";
    }


    public interface OnReactNativeHostListener {
        /**
         * rn exception 回调接口（js->java, java->js）
         *
         * @param e
         */
        void handleException(Exception e);

        /**
         * 当前bridge初始化react context完成时，回调此方法，但是只会调用一次；如果已经提前预热，该方法不会触发。
         *
         * @param reactContext
         */
        void onReactContextInitCompleted(ReactContext reactContext);

        ReactLoadUtils.OnLoadScriptListener getOnLoadScriptListener();

    }
}
